package bma.common.langutil.concurrent;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * Future4Task的简单实现
 * 
 * @author 关中
 * @since 1.0 (imported from BMA.ESP Project)
 * 
 * @param <TYPE>
 */
public class FutureSimple<TYPE> implements Future4Task<TYPE> {

	private boolean done;
	private TYPE result;
	private Throwable exception;

	public FutureSimple() {
		super();
	}

	public FutureSimple(TYPE result) {
		this(result, null);
	}

	public FutureSimple(TYPE result, Throwable exception) {
		super();
		this.done = true;
		this.result = result;
		this.exception = exception;
	}

	@Override
	public boolean cancel(boolean mayInterruptIfRunning) {
		return false;
	}

	protected TYPE _get() throws ExecutionException {
		if (this.exception != null) {
			if (exception instanceof RuntimeException) {
				RuntimeException r = (RuntimeException) exception;
				throw r;
			}
			throw new ExecutionException(this.exception);
		}
		return this.result;
	}

	@Override
	public TYPE get() throws InterruptedException, ExecutionException {
		synchronized (this) {
			if (!done) {
				this.wait();
			}
			return _get();
		}
	}

	@Override
	public TYPE get(long timeout, TimeUnit unit) throws InterruptedException,
			ExecutionException, TimeoutException {
		synchronized (this) {
			if (!done) {
				this.wait(unit.toMillis(timeout));
			}
			return _get();
		}
	}

	@Override
	public boolean isCancelled() {
		return false;
	}

	@Override
	public boolean isDone() {
		synchronized (this) {
			return this.done;
		}
	}

	@Override
	public void done(TYPE value, Throwable t) {
		synchronized (this) {
			this.result = value;
			this.exception = t;
			this.done = true;
			this.notifyAll();
		}
	}

}
